package com.hmall.common.utils;

import cn.hutool.core.bean.BeanUtil;

import java.util.List;
import java.util.stream.Collectors;

/**
 * Bean工具类
 * 继承自Hutool的BeanUtil，扩展了自定义转换器功能
 * 用于对象属性复制和类型转换
 */
public class BeanUtils extends BeanUtil {

    /**
     * 复制单个对象并应用自定义转换器
     * @param source 源对象
     * @param clazz 目标对象Class
     * @param convert 自定义转换器（可为null）
     * @param <R> 源对象类型
     * @param <T> 目标对象类型
     * @return 转换后的目标对象
     */
    public static <R, T> T copyBean(R source, Class<T> clazz, Convert<R, T> convert) {
        // 先使用Hutool的默认复制逻辑
        T target = copyBean(source, clazz);
        // 再应用自定义转换器处理特殊字段
        if (convert != null) {
            convert.convert(source, target);
        }
        return target;
    }

    /**
     * 复制单个对象（无自定义转换）
     * @param source 源对象
     * @param clazz 目标对象Class
     * @param <R> 源对象类型
     * @param <T> 目标对象类型
     * @return 转换后的目标对象
     */
    public static <R, T> T copyBean(R source, Class<T> clazz) {
        // 处理源对象为null的情况
        if (source == null) {
            return null;
        }
        // 调用Hutool的默认转换方法
        return toBean(source, clazz);
    }

    /**
     * 复制对象列表（无自定义转换）
     * @param list 源对象列表
     * @param clazz 目标对象Class
     * @param <R> 源对象类型
     * @param <T> 目标对象类型
     * @return 转换后的目标对象列表
     */
    public static <R, T> List<T> copyList(List<R> list, Class<T> clazz) {
        // 处理列表为空的情况
        if (list == null || list.size() == 0) {
            return CollUtils.emptyList();
        }
        // 使用Java Stream进行批量转换
        return copyToList(list, clazz);
    }

    /**
     * 复制对象列表并应用自定义转换器
     * @param list 源对象列表
     * @param clazz 目标对象Class
     * @param convert 自定义转换器
     * @param <R> 源对象类型
     * @param <T> 目标对象类型
     * @return 转换后的目标对象列表
     */
    public static <R, T> List<T> copyList(List<R> list, Class<T> clazz, Convert<R, T> convert) {
        // 处理列表为空的情况
        if (list == null || list.size() == 0) {
            return CollUtils.emptyList();
        }
        // 遍历列表并应用带转换器的单对象转换
        return list.stream()
                .map(r -> copyBean(r, clazz, convert))
                .collect(Collectors.toList());
    }
}